/*
 * Copyright (c) 2001, 2002 Boris Pruessmann and others. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Common Public License v0.5 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/cpl-v05.html
 * 
 * Contributors: Boris Pruessmann - Initial implementation.
 */
package net.sourceforge.perforce.ui.internal;

import java.text.MessageFormat;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

import net.sourceforge.perforce.core.AssertionError;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.SubProgressMonitor;

/**
 * @version $Revision: 488 $
 * @author <a href="mailto:bpruessmann@users.sourceforge.net">Boris
 *         Pruessmann</a>
 */
public class Policy {
  // --------------------------------------------------------------------
  // Private Static Variables

  /** Stores an instance to the active ResourceBundle. */
  private static ResourceBundle bundle = null;

  // ------------------------------------------------------------------------
  // Private Constructors

  /** Constructor for Policy. Private because Policy is a utility class. */
  private Policy() {
  }

  // -----------------------------------------------------------------------
  // Public Static Methods

  /**
   * Creates a NLS catalog for the given locale.
   * 
   * @param bundleName the name of the bundle.
   */
  public static void localize(String bundleName) {
    bundle = ResourceBundle.getBundle(bundleName);
  }

  /**
   * Lookup the message with the given ID in this catalog and bind its
   * substitution locations with the given string.
   * 
   * @param id the identifier of the message.
   * @param binding Object that is bound to the message.
   * @return the complete message.
   */
  public static String bind(String id, Object binding) {
    return bind(id, new Object[] {binding});
  }

  /**
   * Lookup the message with the given ID in this catalog and bind its
   * substitution locations with the given strings.
   * 
   * @param id the identifier of the message.
   * @param binding1 Object that is bound to the message.
   * @param binding2 Object that is bound to the message.
   * @return the complete message.
   */
  public static String bind(String id, Object binding1, Object binding2) {
    return bind(id, new Object[] {binding1, binding2});
  }

  /**
   * Gets a string from the resource bundle. We don't want to crash because of a
   * missing String.
   * 
   * @param key the identifier of the message.
   * @return the complete message; key if no message found.
   */
  public static String bind(String key) {
    try {
      return bundle.getString(key);
    } catch (MissingResourceException e) {
      return key;
    } catch (NullPointerException e) {
      return '!' + key + '!';
    }
  }

  /**
   * Gets a string from the resource bundle and binds it with the given
   * arguments.
   * 
   * @param key the identifier of the message.
   * @param args arguments to be bound to the message.
   * @return the complete message; key if no message found.
   */
  public static String bind(String key, Object[] args) {
    try {
      return MessageFormat.format(bind(key), args);
    } catch (MissingResourceException e) {
      return key;
    } catch (NullPointerException e) {
      return '!' + key + '!';
    }
  }

  /**
   * Returns a valid progress monitor.
   * 
   * @param monitor the progress monitor or null.
   * @return the progress monitor or a new NullProgressMonitor.
   */
  public static IProgressMonitor monitorFor(IProgressMonitor monitor) {
    if (monitor == null) {
      return new NullProgressMonitor();
    }

    return monitor;
  }

  /** Returns a valid SubProgressMonitor. */
  public static IProgressMonitor subMonitorFor(IProgressMonitor monitor, int ticks) {
    if (monitor == null) {
      return new NullProgressMonitor();
    }

    if (monitor instanceof NullProgressMonitor) {
      return monitor;
    }

    return new SubProgressMonitor(monitor, ticks);
  }

  /** Returns a valid SubProgressMonitor. */
  public static IProgressMonitor subMonitorFor(IProgressMonitor monitor, int ticks, int style) {
    if (monitor == null) {
      return new NullProgressMonitor();
    }

    if (monitor instanceof NullProgressMonitor) {
      return monitor;
    }

    return new SubProgressMonitor(monitor, ticks, style);
  }

  /**
   * Call this method to assert that the given condition is true.
   * 
   * @param condition the condition.
   * @throws AssertionError when the assertion fails.
   */
  public static void assertTrue(boolean condition) throws AssertionError {
    if (!condition) {
      throw new AssertionError("Assertion failed."); //$NON-NLS-1$
    }
  }

  /**
   * Asserts that the given object is an instance of the specified class.
   * 
   * @param object the object.
   * @param clazz the class.
   * @throws AssertionError when the assertion fails.
   */
  public static void assertInstanceOf(Object object, Class<?> clazz) throws AssertionError {
    if (!clazz.isInstance(object)) {
      throw new AssertionError("Assertion failed: object has to be an instance of " + clazz); //$NON-NLS-1$
    }
  }

  /**
   * Asserts that the given string is not empty.
   * 
   * @param text the string.
   * @throws AssertionError when the assertion fails.
   */
  public static void assertNotEmpty(String text) throws AssertionError {
    if (text.length() == 0) {
      throw new AssertionError("Assertion failed: String may not be empty."); //$NON-NLS-1$
    }
  }

  /**
   * Asserts that the given object reference is not null.
   * 
   * @param object the object reference.
   * @throws AssertionError when the assertion fails.
   */
  public static void assertNotNull(Object object) throws AssertionError {
    if (object == null) {
      throw new AssertionError("Assertion failed: object may not be null."); //$NON-NLS-1$
    }
  }

  /**
   * Asserts that the given object reference is null.
   * 
   * @param object the object reference.
   * @throws AssertionError when the assertion fails.
   */
  public static void assertNull(Object object) throws AssertionError {
    if (object != null) {
      throw new AssertionError("Assertion failed: object has to be null."); //$NON-NLS-1$
    }
  }
}
